package com.example.hello;

import com.example.hello.client.TabPanel.BootstrapTabPanelState;
import com.vaadin.shared.Connector;
import com.vaadin.ui.AbstractComponentContainer;
import com.vaadin.ui.Component;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class BootstrapTabPanel extends AbstractComponentContainer {

    public enum Position {
        ABOVE, BELOW, LEFT, RIGHT
    }

    public BootstrapTabPanel() {
        this(Position.ABOVE);
    }

    public BootstrapTabPanel(Position position) {
        setTabPosition(position);
    }

    public BootstrapTabPanel(Position position, List<BootstrapTab> tabs) {
        setTabPosition(position);
        setTabs(tabs);
    }

    public BootstrapTabPanel(Position position, BootstrapTab... tabs) {
        setTabPosition(position);
        for (BootstrapTab tab : tabs) {
            addTab(tab);
        }
    }

    public void BootstrapTabPanel(Component tab) {
        getState().addTab(tab);
    }

    public List<Component> getTabs() {
        List<Component> tabs = new LinkedList<Component>();
        for (Connector connector : getState().getTabs()) {
            tabs.add((Component) connector);
        }

        return tabs;
    }

    public void setTabs(List<BootstrapTab> tabs) {
        List<Connector> connectorList = new LinkedList<Connector>();
        for (BootstrapTab tab : tabs) {
            connectorList.add(tab);
        }

        getState().setTabs(connectorList);
    }

    @Override
    protected BootstrapTabPanelState getState() {
        return (BootstrapTabPanelState) super.getState();
    }

    public int getSelectedTab() {
        return getState().getSelectedTab();
    }

    public Position getTabPosition() {
        return Position.valueOf(getState().getTabPosition());
    }

    public void addTab(Component tab) {
        addTab(tab, getTabs().size());
    }

    private void addTab(Component tab, int index) {
        if (tab.getParent() != null) {
            throw new IllegalArgumentException("Given tabpanel already has a parent component");
        }

        getState().addTab(tab, index);
        super.addComponent(tab);

        markAsDirty();
    }

    public void replaceTab(Component oldTab, Component newTab) {
        if (!getTabs().contains(oldTab)) {
            throw new IllegalArgumentException("Given old tabpanel does not exist in this group");
        }

        int oldIndex = getTabs().indexOf(oldTab);

        if (oldIndex == -1) {
            return;
        }

        removeTab(oldTab);
        addTab(newTab, oldIndex);
    }

    public void removeTab(int index) {
        removeTab(getTabs().get(index));
    }

    public boolean removeTab(Component tab) {
        if (!getTabs().contains(tab)) {
            return false;
        }

        getState().removeTab(tab);
        super.removeComponent(tab);

        markAsDirty();
        return true;
    }

    public void removeAllTabs() {
        super.removeAllComponents();
        getTabs().clear();

        markAsDirty();
    }

    public void setSelectedTab(int selectedTab) {
        getState().setSelectedTab(selectedTab);
    }

    public void setTabPosition(Position tabPosition) {
        getState().setTabPosition(tabPosition.toString());
    }

    public boolean isPullRight() {
        return getState().isPullRight();
    }

    public void setPullRight(boolean pullRight) {
        getState().setPullRight(pullRight);
    }

    @Override
    public void replaceComponent(Component oldComponent, Component newComponent) {
        throw new UnsupportedOperationException("Use replaceTab method instead");
    }

    @Override
    public int getComponentCount() {
        return getTabs().size();
    }

    @Override
    public Iterator<Component> iterator() {
        return getTabs().iterator();
    }

}